﻿
using AutoMapper;
using Enferno.Public.Web.Components.Server.Mappers;
using Enferno.Public.Web.Components.Server.ViewModels;
using Enferno.Public.Web.Models;
using Enferno.StormApiClient.Customers;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Enferno.Public.Web.Components.Test.Server.Mappers
{
    [TestClass]
    public class CheckoutMapperTest
    {
        [TestMethod]
        public void UpdatePrivateInformationTest()
        {
            // ARRANGE
            var models = new TestModels();
            var buyer = models.GetAnonymousBuyer();
            var payer = models.GetAnonymousPrivatePayer();
            var shipTo = models.GetAnonymousPrivateShipTo();

            Mapper.AddProfile(new ComponentsProfile());

            // ACT
            var buyerModel = Mapper.Map<CheckoutBuyerViewModel, CheckoutBuyerModel>(buyer);

            var shipToModel = Mapper.Map<CheckoutPrivateShipToViewModel, CheckoutPrivateShipToModel>(shipTo);
            var shipToCustomer = Mapper.Map<CheckoutPrivateShipToModel, Customer>(shipToModel);
            var buyerCustomer = Mapper.Map<CheckoutPrivateShipToModel, Customer>(shipToModel);

            var payerModel = Mapper.Map<CheckoutPrivatePayerViewModel, CheckoutPrivatePayerModel>(payer);
            var payerCustomer = Mapper.Map<CheckoutBuyerModel, Customer>(buyerModel);
            Mapper.Map(payerModel, payerCustomer);
            Mapper.Map(payerModel, buyerCustomer);

            Mapper.Map(buyerModel, buyerCustomer);

            // ASSERT
            Assert.AreEqual(buyer.FirstName, buyerCustomer.FirstName);
            Assert.AreEqual(buyer.LastName, buyerCustomer.LastName);
            Assert.AreEqual(buyer.Email, buyerCustomer.Email);
            Assert.AreEqual(buyer.CellPhone, buyerCustomer.CellPhone);

            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, buyerCustomer.InvoiceAddress);
            Assert.AreEqual(payer.SocialSecurityNumber, buyerCustomer.SSN);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, buyerCustomer.DeliveryAddresses[0]);

            AssertPersonalInformationEqualsCustomer(payer.PersonInformation, payerCustomer);
            Assert.AreEqual(payer.SocialSecurityNumber, payerCustomer.SSN);
            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, payerCustomer.InvoiceAddress);

            AssertPersonalInformationEqualsCustomer(shipTo.PersonInformation, shipToCustomer);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, shipToCustomer.DeliveryAddresses[0]);
        }

        [TestMethod]
        public void UpdatePrivateInformationBuyerWithoutEmailPhoneTest()
        {
            // ARRANGE
            var models = new TestModels();
            var buyer = models.GetAnonymousBuyerWithoutEmailPhone();
            var payer = models.GetAnonymousPrivatePayer();
            var shipTo = models.GetAnonymousPrivateShipTo();

            Mapper.AddProfile(new ComponentsProfile());

            // ACT
            var buyerModel = Mapper.Map<CheckoutBuyerViewModel, CheckoutBuyerModel>(buyer);

            var shipToModel = Mapper.Map<CheckoutPrivateShipToViewModel, CheckoutPrivateShipToModel>(shipTo);
            var shipToCustomer = Mapper.Map<CheckoutPrivateShipToModel, Customer>(shipToModel);
            var buyerCustomer = Mapper.Map<CheckoutPrivateShipToModel, Customer>(shipToModel);

            var payerModel = Mapper.Map<CheckoutPrivatePayerViewModel, CheckoutPrivatePayerModel>(payer);
            var payerCustomer = Mapper.Map<CheckoutBuyerModel, Customer>(buyerModel);
            Mapper.Map(payerModel, payerCustomer);
            Mapper.Map(payerModel, buyerCustomer);

            Mapper.Map(buyerModel, buyerCustomer);

            // ASSERT
            Assert.AreEqual(buyer.FirstName, buyerCustomer.FirstName);
            Assert.AreEqual(buyer.LastName, buyerCustomer.LastName);
            Assert.AreEqual(payer.PersonInformation.Email, buyerCustomer.Email);
            Assert.AreEqual(payer.PersonInformation.CellPhone, buyerCustomer.CellPhone);

            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, buyerCustomer.InvoiceAddress);
            Assert.AreEqual(payer.SocialSecurityNumber, buyerCustomer.SSN);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, buyerCustomer.DeliveryAddresses[0]);

            AssertPersonalInformationEqualsCustomer(payer.PersonInformation, payerCustomer);
            Assert.AreEqual(payer.SocialSecurityNumber, payerCustomer.SSN);
            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, payerCustomer.InvoiceAddress);

            AssertPersonalInformationEqualsCustomer(shipTo.PersonInformation, shipToCustomer);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, shipToCustomer.DeliveryAddresses[0]);
        }

        [TestMethod]
        public void UpdateCompanyInformationTest()
        {
            // ARRANGE
            var models = new TestModels();
            var buyer = models.GetAnonymousBuyer();
            var payer = models.GetAnonymousCompanyPayer();
            var shipTo = models.GetAnonymousCompanyShipTo();

            Mapper.AddProfile(new ComponentsProfile());

            // ACT
            var buyerModel = Mapper.Map<CheckoutBuyerViewModel, CheckoutBuyerModel>(buyer);

            var shipToModel = Mapper.Map<CheckoutCompanyShipToViewModel, CheckoutCompanyShipToModel>(shipTo);
            var shipToCustomer = Mapper.Map<CheckoutCompanyShipToModel, Customer>(shipToModel);
            var buyerCustomer = Mapper.Map<CheckoutCompanyShipToModel, Customer>(shipToModel);

            var payerModel = Mapper.Map<CheckoutCompanyPayerViewModel, CheckoutCompanyPayerModel>(payer);
            var payerCustomer = Mapper.Map<CheckoutBuyerModel, Customer>(buyerModel);
            Mapper.Map(payerModel, payerCustomer);
            Mapper.Map(payerModel, buyerCustomer);

            Mapper.Map(buyerModel, buyerCustomer);

            // ASSERT
            Assert.AreEqual(buyer.FirstName, buyerCustomer.FirstName);
            Assert.AreEqual(buyer.LastName, buyerCustomer.LastName);
            Assert.AreEqual(buyer.Email, buyerCustomer.Email);
            Assert.AreEqual(buyer.CellPhone, buyerCustomer.CellPhone);

            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, buyerCustomer.Companies[0].InvoiceAddress);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, buyerCustomer.Companies[0].DeliveryAddresses[0]);
            Assert.IsNull(buyerCustomer.SSN);

            Assert.AreEqual(buyer.Email, payerCustomer.Email);
            Assert.AreEqual(buyer.CellPhone, payerCustomer.CellPhone);
            Assert.AreEqual(payer.CompanyInformation.Name, payerCustomer.Companies[0].Name);
            Assert.AreEqual(payer.OrganisationNumber, payerCustomer.Companies[0].OrgNo);
            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, payerCustomer.Companies[0].InvoiceAddress);

            Assert.AreEqual(shipTo.CompanyInformation.Name, shipToCustomer.Companies[0].Name);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, buyerCustomer.Companies[0].DeliveryAddresses[0]);
        }

        [TestMethod]
        public void UpdateCompanyInformationWithoutEmailPhoneTest()
        {
            // ARRANGE
            var models = new TestModels();
            var buyer = models.GetAnonymousBuyerWithoutEmailPhone();
            var payer = models.GetAnonymousCompanyPayer();
            var shipTo = models.GetAnonymousCompanyShipTo();

            Mapper.AddProfile(new ComponentsProfile());

            // ACT
            var buyerModel = Mapper.Map<CheckoutBuyerViewModel, CheckoutBuyerModel>(buyer);

            var shipToModel = Mapper.Map<CheckoutCompanyShipToViewModel, CheckoutCompanyShipToModel>(shipTo);
            var shipToCustomer = Mapper.Map<CheckoutCompanyShipToModel, Customer>(shipToModel);
            var buyerCustomer = Mapper.Map<CheckoutCompanyShipToModel, Customer>(shipToModel);

            var payerModel = Mapper.Map<CheckoutCompanyPayerViewModel, CheckoutCompanyPayerModel>(payer);
            var payerCustomer = Mapper.Map<CheckoutBuyerModel, Customer>(buyerModel);
            Mapper.Map(payerModel, payerCustomer);
            Mapper.Map(payerModel, buyerCustomer);

            Mapper.Map(buyerModel, buyerCustomer);

            // ASSERT
            Assert.AreEqual(buyer.FirstName, buyerCustomer.FirstName);
            Assert.AreEqual(buyer.LastName, buyerCustomer.LastName);
            Assert.AreEqual(buyer.Email, buyerCustomer.Email);
            Assert.AreEqual(buyer.CellPhone, buyerCustomer.CellPhone);

            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, buyerCustomer.Companies[0].InvoiceAddress);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, buyerCustomer.Companies[0].DeliveryAddresses[0]);
            Assert.IsNull(buyerCustomer.SSN);
            
            Assert.AreEqual(buyer.Email, payerCustomer.Email);
            Assert.AreEqual(buyer.CellPhone, payerCustomer.CellPhone);
            Assert.AreEqual(payer.CompanyInformation.Name, payerCustomer.Companies[0].Name);
            Assert.AreEqual(payer.OrganisationNumber, payerCustomer.Companies[0].OrgNo);
            AssertAddressViewModelEqualsAddress(payer.InvoiceAddress, payerCustomer.Companies[0].InvoiceAddress);

            Assert.AreEqual(shipTo.CompanyInformation.Name, shipToCustomer.Companies[0].Name);
            AssertAddressViewModelEqualsAddress(shipTo.DeliveryAddress, shipToCustomer.Companies[0].DeliveryAddresses[0]);
        }

        private static void AssertAddressViewModelEqualsAddress(AddressViewModel addressModel, Address address)
        {
            Assert.AreEqual(addressModel.Line1, address.Line1);
            Assert.AreEqual(addressModel.Zip, address.Zip);
            Assert.AreEqual(addressModel.City, address.City);
            Assert.AreEqual(addressModel.Country, address.Country);
        }

        private static void AssertPersonalInformationEqualsCustomer(PersonInformationViewModel personInformation, Customer customer)
        {
            Assert.AreEqual(personInformation.FirstName, customer.FirstName);
            Assert.AreEqual(personInformation.LastName, customer.LastName);
            Assert.AreEqual(personInformation.Email, customer.Email);
            Assert.AreEqual(personInformation.CellPhone, customer.CellPhone);
        }
    }
}
